//
// Created by YE on 2024/1/7.
//

#ifndef YCH_INTERPRETER_YCH_CODE_H
#define YCH_INTERPRETER_YCH_CODE_H
#include "../common/ych_object.h"
/*code
+--------+---------+---------+--------+--------+
|  iABC  |    C:9  |   B:9   |   A:7  |Opcode:7|  B,C R  A R
+--------+---------+---------+--------+--------+
|  iABx  |   Bx:18(unsigned) |   A:7  |Opcode:7| Bx内存寻址 A寄存器
+--------+---------+---------+--------+--------+
*/
#define SIZE_OP 7
#define SIZE_A  7
#define SIZE_B  9
#define SIZE_C  9

#define OFFSET_A SIZE_OP
#define OFFSET_B (SIZE_A + SIZE_OP)
#define OFFSET_C (SIZE_B + SIZE_A + SIZE_OP)

#define SET_ARG_A(i, r) (i = (i & 0xFFFFC07F) | r << 7)
#define SET_ARG_B(i, r) (i = (i & 0xFF803FFF) | r << 14)
#define SET_ARG_C(i, r) (i = (i & 0x007FFFFF) | r << 23)
#define SET_ARG_Bx(i,r) (i = (i & 0x00003FFF) | r << 14)
#define GET_OPCODE(i) (i & 0x7F)
#define GET_ARG_A(i) ((i & 0x3F80) >> OFFSET_A)
#define GET_ARG_B(i) ((i & 0x7FC000) >> OFFSET_B)
#define GET_ARG_C(i) ((i & 0xFF800000) >> OFFSET_C)
#define GET_ARG_Bx(i) ((i & 0xFFFFC000) >> (SIZE_A + SIZE_OP))
typedef unsigned int Instruction;

typedef void(*CFV0)();
typedef Object(*CFO1)(Object *);
typedef Object(*CFO2)(Object *,Object *);
typedef void(*CFV2)(Object *,Object *);
typedef Object(*CFO3)(Object *,Object *,Object *);
typedef void(*CFV4)(Object *,Object *,Object *,Object *);
typedef Object(*CFO4)(Object *,Object *,Object *,Object *);
enum CFT{
    CFT_V0,
    CFT_O1,
    CFT_V2,
    CFT_O2,
    CFT_O3,
    CFT_V4,
    CFT_O4,
};

enum OP{
    OP_END,
    OP_MOV,// a=0,1 S[func_start_pos+bx]->R[a];a=2 Immediate number bx->R[2]; a=3 S[top]->R[3] ;a=4 b->R[4],c->R[5];a=5 M[Bx][R[4].v.p][R[5].v.p]=R[1].v.f
    //a=6 S[func_start_pos+bx][R[4].v.p][R[5].v.p]=R[1].v.f ; a=7 R[7]->R[3]
    OP_LOAD_M, //M[Bx]->R[A]
    OP_STORE_M,//R[A]->M[Bx]
    OP_LOAD_I,//INTCONST[Bx]->R[A]
    OP_LOAD_F,//FLOATCONST[Bx]->R[A]
    OP_LOAD_S,//S[top]->R[a]
    OP_LOAD_B,//R[a]=bx
    OP_LOAD_STR,//STR_CONST[Bx]=>R[A]
    OP_ADD,OP_SUB,
    OP_MUL,OP_IMUL,OP_DIV,OP_MOD, OP_POW,
    OP_NEG,OP_LESS,OP_GREATER,OP_LESSEQUAL,OP_GREATEREQUAL,OP_EQUAL,OP_NOTEQUAL,
    OP_NOT,OP_AND,OP_OR,OP_ASSIGN,
    OP_POP,OP_POPP,OP_CJUMPF,OP_CJUMPR,OP_JUMP,
    OP_CALL,// A index the function in the reg.
            // B represents the number of params,
            // it means that the function parameters range from A+1 to the top of stack
    OP_LEV,
    OP_CALL_C,//a Cfunc类型 bx Cfunc位置
    OP_PUSH,//R[a]->S[top]
    OP_MALLOC_MAT,
    OP_INDEX,OP_GC
};

#endif //YCH_INTERPRETER_YCH_CODE_H
